package com.kk.nio.telnet.server;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * 服务端多路选择器
* 源文件名：MultServerSelector.java
* 文件版本：1.0.0
* 创建作者：liujun
* 创建日期：2016年11月6日
* 修改作者：liujun
* 修改日期：2016年11月6日
* 文件描述：liujun
* 版权所有：Copyright 2016 zjhz, Inc. All Rights Reserved.
*/
public class MultServerSelector implements Runnable {

    /**
     * 服务端选择器对象
    * @字段说明 serverSelect
    */
    private Selector serverSelect;

    /**
     * 服务器通道
    * @字段说明 serverSocketChan
    */
    private ServerSocketChannel serverSocketChan;

    /**
     * 是否运行
    * @字段说明 isRun
    */
    private volatile boolean isRun = true;

    public MultServerSelector(int port) throws IOException {
        this.serverSelect = Selector.open();
        // 打开服务器通道
        this.serverSocketChan = ServerSocketChannel.open();
        // 设置为非阻塞
        this.serverSocketChan.configureBlocking(false);
        // 绑定端口
        this.serverSocketChan.bind(new InetSocketAddress(port));

        this.serverSocketChan.register(serverSelect, SelectionKey.OP_ACCEPT);
    }

    @SuppressWarnings("static-access")
    @Override
    public void run() {
        while (isRun) {
            try {
                this.serverSelect.select(500);
                Iterator<SelectionKey> selectKeyIter = serverSelect.selectedKeys().iterator();

                while (selectKeyIter.hasNext()) {
                    SelectionKey item = selectKeyIter.next();

                    // 如果当前是连接事件
                    if ((item.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
                        ServerSocketChannel serverSocketChan = (ServerSocketChannel) item.channel();
                        SocketChannel socketClient = serverSocketChan.accept();
                        // 设置为非阻塞
                        socketClient.configureBlocking(false);
                        socketClient.register(serverSelect, SelectionKey.OP_READ);
                        // 回写消息
                        socketClient.write(ByteBuffer.wrap("WeleComde to liujun telnet Server ....\r\n".getBytes()));
                        socketClient.write(ByteBuffer.wrap("please input \r\n".getBytes()));
                    }

                    else if ((item.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
                        SocketChannel channel = (SocketChannel) item.channel();

                        ByteBuffer buffReadMsg = ByteBuffer.allocate(512);
                        channel.read(buffReadMsg);

                        StringBuilder currMsg = (StringBuilder) item.attachment();

                        if (null == currMsg) {
                            currMsg = new StringBuilder();
                        }

                        StringBuilder msg = new StringBuilder();
                        buffReadMsg.flip();
                        msg.append(new String(buffReadMsg.array()));

                        System.out.println("收到的信息:" + msg.toString());

                        // 通过中间接收信息
                        if (msg.indexOf("\n") == -1) {
                            currMsg.append(msg);
                            item.attach(currMsg);
                        } else {
                            currMsg.append(msg);
                            byte[] outValue = currMsg.toString().getBytes();

                            ByteBuffer buffReadMsgOut = ByteBuffer.allocate(outValue.length);
                            buffReadMsgOut.put(outValue);
                            buffReadMsgOut.flip();
                            channel.write(buffReadMsgOut);

                            item.attach(null);
                        }

                    }

                    selectKeyIter.remove();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) {

        StringBuilder msg = new StringBuilder();

        for (int i = 0; i < 10; i++) {
            msg.append(" this is msg test !");
        }

        String outByteArrayMsg = msg.toString();

        outByteArrayMsg = outByteArrayMsg.substring(0, outByteArrayMsg.length() - 5);

        System.out.println("输入:" + outByteArrayMsg);

        ByteArrayInputStream input = new ByteArrayInputStream(outByteArrayMsg.getBytes());

        int length = 10;

        ByteBuffer buffermsg = ByteBuffer.allocate(length);

        byte[] buffByte = new byte[length];

        StringBuilder outMsg = new StringBuilder();

        int index = -1;
        try {
            while ((index = input.read(buffByte)) != -1) {
                if (index == 5) {
                    System.out.println("当前为最后一次:");
                }
                buffermsg.put(buffByte, 0, index);
                buffermsg.flip();
                outMsg.append(new String(buffermsg.array()));
                buffermsg.clear();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("输出:" + outMsg.toString());

    }

}
